 package org.springframework.remoting.server.util;
 
 import java.lang.reflect.Field;

import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;
import org.springframework.util.ClassUtils;
 
 
 
 
 public class AopTargetUtils{
	 /** 
	     * 获取 目标对象 
	     * @param proxy 代理对象 
	     * @return  
	     * @throws Exception 
	     */  
	    public static Object getTarget(Object proxy) throws Exception {  
	          
	        if(!AopUtils.isAopProxy(proxy)) {  
	            return proxy;//不是代理对象  
	        }  
	          
	        if(AopUtils.isJdkDynamicProxy(proxy)) {  
	            return getJdkDynamicProxyTargetObject(proxy);  
	        } else { //cglib  
	            return getCglibProxyTargetObject(proxy);  
	        }  
	    }  
   
   private static Object getCglibProxyTargetObject(Object proxy)
     throws Exception
   {
     Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
     h.setAccessible(true);
     Object dynamicAdvisedInterceptor = h.get(proxy);
     
     Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
     advised.setAccessible(true);
     Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
     return target;
   }
   
   private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception
   {
     Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
     h.setAccessible(true);
     AopProxy aopProxy = (AopProxy)h.get(proxy);
     Field advised = aopProxy.getClass().getDeclaredField("advised");
     advised.setAccessible(true);
     Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
     return target;
   }
 
   public static String getRawClassName(Object object)
   {
     if (object != null) {
       if (AopUtils.isAopProxy(object)) {
         String v = AopUtils.getTargetClass(object).getName();
         if ((v.contains("$Proxy")) || (v.contains("$$"))) {
           try {
             Object o = ((Advised)object).getTargetSource().getTarget();
             return getRawClassName(o);
           }
           catch (Exception localException) {}
         } else {
           return v;
         }
       } else {
         if (ClassUtils.isCglibProxyClass(object.getClass())) {
           return AopUtils.getTargetClass(object).getName();
         }
         return object.getClass().getName();
       }
     }
     return "UnknowClass";
   }
 }